package com.shijie.service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.shijie.domain.entity.*;
import com.shijie.mapper.*;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import tk.mybatis.mapper.entity.Example;

import com.shijie.component.ErpUserService;
import com.shijie.core.AbstractService;
import com.shijie.core.ServiceException;
import com.shijie.domain.enums.EnumInterface;
import com.shijie.domain.enums.EnumInterface.PayType;
import com.shijie.domain.vo.BaseUserVo;
import com.shijie.domain.vo.UserPayInformation;
import com.shijie.utils.DateUtil;

/*
 *  @author: smart boy
 *  @date: 2018-08-06
 */
@Service
public class UserOrdersService extends AbstractService<UserOrders> {

	@Resource
	private UserOrdersMapper userOrdersMapper;

    @Resource
    private UserCouponsMapper userCouponsMapper;

    @Resource
    private GrouponsMapper grouponsMapper;

    @Resource
    private UserGrouponsMapper userGrouponsMapper;

    @Resource
    private CouponsMapper couponsMapper;

    @Resource
    private ProductsMapper productsMapper;

    @Resource
    private SkusMapper skusMapper;

    @Resource
    private MagazinesMapper magazinesMapper;

    @Resource
    private UsersMapper usersMapper;

    @Resource
    private SignsMapper signsMapper;
    
    @Resource
    private LogisticCompanysMapper logisticCompanysMapper;
    
    @Resource
    private UserAddressMapper  userAddressMapper;
    @Resource
    private BrandsMapper brandsMapper;
    @Resource
    private ErpUserService  erpUserService;

    @Resource
    private TalentTrialsService talentTrialsService;
    


	public List<UserOrders> selectOrdersForUser(UserOrders qCondition) {
        Example con = new Example(UserOrders.class);
        Example.Criteria criteria = con.createCriteria();
        if (qCondition.getBuyerId() != null) {
            criteria.andEqualTo("buyerId", qCondition.getBuyerId());
        }
        if (qCondition.getBuyerName() != null) {
            criteria.andEqualTo("buyerName", qCondition.getBuyerName());
        }
        if (qCondition.getEntityType() != null) {
            criteria.andEqualTo("entityType", qCondition.getEntityType());
        }
        if (qCondition.getStatus() != null) {
            criteria.andEqualTo("status", qCondition.getStatus());
        }
        con.orderBy("status").asc().orderBy("createTime").desc();

        List<UserOrders> lists = userOrdersMapper.selectByCondition(con);

        for (UserOrders order : lists) {
            if (order.getEntityType().compareTo(EnumInterface.EntityType.ACTIVITY.ordinal()) == 0) {
                // 活动
                order.setMagazine(magazinesMapper.selectByPrimaryKey(order.getEntityId()));
            } else if (order.getEntityType().compareTo(EnumInterface.EntityType.PRODUCT.ordinal()) == 0) {
                // 商品
                order.setProduct(productsMapper.selectByPrimaryKey(order.getEntityId()));
                order.setSku(skusMapper.selectByPrimaryKey(order.getSkuId()));
            }

        }
        return lists;
    }

    public BigDecimal selectPayAmount(String paymentSerial) {
        return userOrdersMapper.selectAmount(paymentSerial);
    }

    /**
     * 记录支付信息
     *
     * @param paymentSerial
     * @param paymentNo
     * @return
     */
    public void updatePayMsg(String paymentSerial, String paymentNo) {

        Example con = new Example(UserOrders.class);
        con.createCriteria().andEqualTo("paymentSerial", paymentSerial);

        UserOrders update = new UserOrders();
        update.setPaymentNo(paymentNo);

        userOrdersMapper.updateByConditionSelective(update, con);


    }


    /**
     * 微信支付成功回调处理
     *
     * @param paymentSerial
     */
    public void paySuccessBySerialNum(String paymentSerial) {

        Example con = new Example(UserOrders.class);
        con.createCriteria().andEqualTo("paymentSerial", paymentSerial);

        UserOrders update = new UserOrders();
        update.setStatus(EnumInterface.PayType.WAIT_DELIVERY.ordinal());

        userOrdersMapper.updateByConditionSelective(update, con);

        UserOrders order = userOrdersMapper.selectByCondition(con).get(0);

        Users user = usersMapper.detailForUser(order.getBuyerId());

        if (paymentSerial.startsWith("ACTIVITY_")) {
            // 活动报名的，生成活动报名信息
            Signs sign = new Signs();
            sign.setActivityId(order.getEntityId());
            sign.setUserId(order.getBuyerId());
            sign.setUserName(order.getBuyerName());
            sign.setFee(order.getActTotalAmount());
            sign.setRegistrationDate(order.getOrderAt());
            sign.setAvatar(user.getAvatar());
            sign.setPhoneNo(user.getPhoneNo());
            sign.setIsUsed(EnumInterface.IsUsed.NOUSED.ordinal());
            sign.setCreateBy(order.getBuyerName());
            sign.setCreateTime(new Date());

            signsMapper.insert(sign);
        }else if(paymentSerial.startsWith("GROUPON_")) {
            UserGroupons userGroupons = new UserGroupons();

            userGroupons.setUserId(order.getBuyerId());
            userGroupons.setGrouponId(order.getEntityId());
            userGroupons.setCreateDate(new Date());
            userGroupons.setPayStatus(PayType.WAIT_DELIVERY.ordinal());
            userGroupons.setStatus(EnumInterface.Status.VALID.ordinal());

            userGrouponsMapper.insert(userGroupons);

        } else if (paymentSerial.startsWith("ACTIVITY_")) {
            // 插入达人的试用数据
            talentTrialsService.saveById(user.getId(), order.getProduct().getId());
        }


    }

    @Transactional
    public String saveOrders(UserPayInformation userPayInformation, BaseUserVo buyer) throws ServiceException {
        if (userPayInformation.getEntityType() == null) {
            throw new ServiceException("EntityType 支付类型必传！");
        }
        if (userPayInformation.getEntityType().compareTo(EnumInterface.EntityType.PRODUCT.ordinal()) == 0 &&
                userPayInformation.getUserAddressId() == null) {
            throw new ServiceException("支付商品时，客户的收货地址必传");
        }

        // 支付流水号
        String paymentSerial = new String();

        if (userPayInformation.getEntityType().compareTo(EnumInterface.EntityType.PRODUCT.ordinal()) == 0) {
            // 商品支付
            paymentSerial = "PRODUCT_" + buyer.getId() + new Date().getTime();
        } else if (userPayInformation.getEntityType().compareTo(EnumInterface.EntityType.ACTIVITY.ordinal()) == 0) {
            // 线下活动报名
            paymentSerial = "ACTIVITY_" + buyer.getId() + new Date().getTime();
        } else if(userPayInformation.getEntityType().compareTo(EnumInterface.EntityType.GROUPON.ordinal()) == 0){
            // 团购支付
            paymentSerial = "GROUPON_" + buyer.getId() + new Date().getTime();
        }


        // 处理优惠券信息
        UserCoupons userCoupon = null;
        Coupons coupon = null;
        Integer useorderNum = 0;


        if(userPayInformation.getUserCouponId() != null) {
            userCoupon = userCouponsMapper.selectByPrimaryKey(userPayInformation.getUserCouponId());
            if (userCoupon == null) {
                throw new ServiceException("传入的用户优惠券ID，非正常数据，请核实！");
            }
            coupon = couponsMapper.selectByPrimaryKey(userCoupon.getCouponId());
            if(coupon == null){
                throw new ServiceException("优惠券信息异常，请核实后台数据！");
            }
        }


        // 生成订单
        for (UserOrders order : userPayInformation.getUserOrders()) {
            if (order.getEntityId() == null) {
                throw new ServiceException("EntityId 支付主键ID必传！");
            }

            if (userPayInformation.getEntityType().compareTo(EnumInterface.EntityType.PRODUCT.ordinal()) == 0) {
                if (order.getSkuId() == null || order.getTotalNum() == null) {
                    throw new ServiceException("支付商品时，skuId totalNum 必传！");
                }
                // 商品支付
                Skus sku = skusMapper.selectByPrimaryKey(order.getSkuId());
                Products product = productsMapper.selectByPrimaryKey(order.getEntityId());
                order.setBrandId(product.getBrandId());
                order.setAddressId(userPayInformation.getUserAddressId());
                order.setPrice(sku.getPrice());
                BigDecimal totolFee = sku.getPrice().multiply(new BigDecimal(order.getTotalNum()));
                order.setTotalAmount(totolFee);
                order.setActTotalAmount(totolFee);
                order.setEntityName(product.getTitle());
                // 判断是否可用于优惠券的商品数量
                if (coupon != null && (coupon.getBrandId().compareTo(0) == 0 || coupon.getBrandId().compareTo(product.getBrandId()) == 0)) {
                    useorderNum = useorderNum + 1;
                }

            } else if (userPayInformation.getEntityType().compareTo(EnumInterface.EntityType.ACTIVITY.ordinal()) == 0) {
                // 线下活动报名
                Magazines magazine = magazinesMapper.selectByPrimaryKey(order.getEntityId());

                if (magazine == null) throw new ServiceException("报名活动不存在");

                Example con = new Example(Signs.class);
                Example.Criteria criteria = con.createCriteria();
                criteria.andEqualTo("activityId", order.getEntityId());

                Integer total = signsMapper.selectCountByCondition(con);

                if (total.compareTo(magazine.getLimits()) >= 0) {
                    throw new ServiceException("报名人数已够！");
                }
                if (DateTime.now().isBefore(magazine.getStartTime().getTime())) {
                    throw new ServiceException("活动未开始");
                }
                if (DateTime.now().isAfter(magazine.getEndTime().getTime())) {
                    throw new ServiceException("活动已结束");
                }

                criteria.andEqualTo("userId", buyer.getId());
                Integer count = signsMapper.selectCountByCondition(con);
                if (count > 0) {
                    throw new ServiceException("该用户已经报过名");
                }

                order.setTotalNum(1);
                order.setPrice(magazine.getFee());
                order.setTotalAmount(magazine.getFee());
                order.setActTotalAmount(magazine.getFee());
                order.setEntityName(magazine.getTitle());

            } else if (userPayInformation.getEntityType().compareTo(EnumInterface.EntityType.GROUPON.ordinal()) == 0) {
                // 团购报名
                Groupons groupon = grouponsMapper.selectByPrimaryKey(order.getEntityId());
                if (DateTime.now().isBefore(groupon.getStartDate().getTime())) {
                    throw new ServiceException("活动未开始！");
                }
                if (DateTime.now().isAfter(groupon.getEndDate().getTime())) {
                    throw new ServiceException("活动已结束！");
                }

                Example con1 = new Example(UserGroupons.class);
                Example.Criteria criteria1 = con1.createCriteria();
                criteria1.andEqualTo("grouponId", order.getEntityId());
                criteria1.andEqualTo("payStatus", PayType.WAIT_DELIVERY.ordinal());
                criteria1.andEqualTo("status", EnumInterface.Status.VALID.ordinal());

                Integer groupNum = userGrouponsMapper.selectCountByCondition(con1);

                if (groupNum >= groupon.getOnsNumber()) {
                    throw new ServiceException("开团人数已满，请查看别的团购！");
                }

                Example con2 = new Example(UserGroupons.class);
                Example.Criteria criteria2 = con2.createCriteria();
                criteria2.andEqualTo("grouponId", order.getEntityId());
                criteria2.andEqualTo("userId", buyer.getId());

                Integer count = userGrouponsMapper.selectCountByCondition(con2);
                if (count > 0) {
                    throw new ServiceException("该用户已经报过名！");
                }

                order.setTotalNum(1);
                order.setPrice(groupon.getPrice());
                order.setTotalAmount(groupon.getPrice());
                order.setActTotalAmount(groupon.getPrice());
                order.setEntityName("团购-" + groupon.getProductName());

            }


            order.setEntityType(userPayInformation.getEntityType());
            order.setStatus(EnumInterface.PayType.UNPAID.ordinal());
            order.setBuyerId(buyer.getId());
            order.setBuyerName(buyer.getTrueName() == null ? buyer.getTrueName() : buyer.getNickName());
            order.setCreateTime(new Date());
            order.setCreateBy(buyer.getTrueName() == null ? buyer.getTrueName() : buyer.getNickName());
            order.setOrderAt(new Date());
            order.setPayLimitAt(DateUtil.addHour(new Date(), 24));
            order.setPaymentSerial(paymentSerial);
            userOrdersMapper.insert(order);

        }

        // 优惠券信息更新到订单中
        if (useorderNum.compareTo(0) > 0) {
            StringBuffer userOrders = new StringBuffer();
            BigDecimal leftFavorableAmount = coupon.getFavorablePrice();
            BigDecimal favorableAmount = coupon.getFavorablePrice().divide(BigDecimal.valueOf(useorderNum), 2, RoundingMode.DOWN);
            for (UserOrders order : userPayInformation.getUserOrders()) {
                if (coupon.getBrandId().compareTo(0) == 0 || coupon.getBrandId().compareTo(order.getBrandId()) == 0) {
                    UserOrders update = new UserOrders();
                    useorderNum = useorderNum - 1;
                    BigDecimal favFee = new BigDecimal(0);
                    if (useorderNum == 0) {
                        favFee = leftFavorableAmount;
                        userOrders.append(order.getId());
                    } else {
                        favFee = favorableAmount;
                        leftFavorableAmount = leftFavorableAmount.subtract(favorableAmount);
                        userOrders.append(order.getId()+",");
                    }
                    order.setFavorableAmount(favFee);
                    order.setActTotalAmount(order.getActTotalAmount().subtract(favFee));

                    update.setActTotalAmount(order.getActTotalAmount());
                    update.setFavorableAmount(order.getFavorableAmount());
                    update.setId(order.getId());

                    userOrdersMapper.updateByPrimaryKeySelective(update);
                }
            }

            // 更新用户优惠券使用状态
            UserCoupons update = new UserCoupons();
            update.setUseOrders(userOrders.toString());
            update.setUseDate(new Date());
            update.setStatus(EnumInterface.IsUsed.USED.ordinal());
            update.setId(userCoupon.getId());

            userCouponsMapper.updateByPrimaryKeySelective(update);

        }

        return paymentSerial;
    }
    
    /**
     * @param order
     */
    public void update(UserOrders order){
    	Assert.notNull(order.getId()  == null, "订单编号不能为空");
    	UserOrders updateOrder  = new UserOrders();
    	updateOrder.setId(order.getId());
    	LogisticCompanys company = logisticCompanysMapper.selectByPrimaryKey(Long.parseLong(order.getLogisticCom()));
        updateOrder.setLogisticEn(company.getCompanyEn());
    	updateOrder.setLogisticCom(company.getCompanyCn());
    	updateOrder.setLogisticNo(order.getLogisticNo());
    	updateOrder.setLogisticAt(DateTime.now().toDate());
    	updateOrder.setStatus(PayType.HAVE_DELIVERY.ordinal());
    	userOrdersMapper.updateByPrimaryKeySelective(updateOrder);
    }


    /**
     * 根据用户ID，获取用户用户中心角标
     *
     *
     *
     * @param userId
     * @return
     */
    public Map<String ,Integer> selectCornerMark(Integer userId){

        Map<String, Integer> numMap = new HashMap<String, Integer>();
        // `status` int(11) DEFAULT '0' COMMENT '状态 0待支付、1 代发货（已支付）、2 已发货（待收货）、3 待评价（已收货）、4 已完成、5 取消（关闭） '
        numMap.put("0", 0);
        numMap.put("1", 0);
        numMap.put("2", 0);
        numMap.put("3", 0);
        numMap.put("4", 0);
        numMap.put("5", 0);

        List<Map<String, String>> query = userOrdersMapper.getSubscriptsByUserid(userId);

        if (query != null && query.size() > 0) {
            for (Map<String, String> map : query) {
                numMap.put(map.get("status"), Integer.parseInt(String.valueOf(map.get("num"))));
            }
        }

        return numMap;
    }
    
    public UserOrders selectById(Integer id){
    	UserOrders order = userOrdersMapper.selectByPrimaryKey(id);
    	if(order.getAddressId() != null){
    		UserAddress address = userAddressMapper.selectByPrimaryKey(order.getAddressId());	
    		if(address != null){
    			order.setAddressName(address.getProvinceName()+address.getCityName()+address.getAreaName()+address.getAddress()+address.getRecName()+"("+address.getRecMobile()+"");
    		}
    	}
    	if(order.getBrandId()!= null){
    		Brands brand = brandsMapper.selectByPrimaryKey(order.getBrandId());
    		order.setBrandName(brand!=null?brand.getName():null);
    	}
    	if(order.getSkuId() != null){
    		order.setSku(skusMapper.selectByPrimaryKey(order.getSkuId()));
    	}
    	return order;
    }
    
    public void updateOrderStatus(int orderId,int status){
    	UserOrders order = new UserOrders();
    	order.setId(orderId);
    	order.setStatus(status);
    	order.setUpdateBy(erpUserService.getUserName());
    	order.setUpdateTime(DateTime.now().toDate());
    	userOrdersMapper.updateByPrimaryKeySelective(order);
    }
}
